/*
 * common 0.0.1 - 通用js
 *
 * Copyright (c) 2008 蓝鸟 (9wee.com)
 *
 *
 * $Date: 2008-12-22 $
 * $Rev: 01 $
 *
 --------------------------------------------------
 更新日志


 */

//调试时使用
var IS_DEBUG = false;


/*
 *
 * 用途：浏览器判断
 * from jquery
 */


var browser = (function() {//
	var userAgent = navigator.userAgent.toLowerCase();
	return {
		version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [])[1],
		safari: /webkit/.test( userAgent ),
		opera: /opera/.test( userAgent ),
		msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),
		mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
	};
})();


/*
 * 用途：得到浏览器的相关数值
 * getWindowX/Y( ): return the position of the window on the screen
 * getViewportWidth/Height( ): return the size of the browser viewport area
 * getDocumentWidth/Height( ): return the size of the document
 * getHorizontalScroll( ): return the position of the horizontal scrollbar
 * getVerticalScroll( ): return the position of the vertical scrollbar
 * from javascript - the definitive Guide 5th
 */
if (window.screenLeft) { // IE and others
    browser.getWindowX = function() { return window.screenLeft; };
    browser.getWindowY = function() { return window.screenTop; };
}
else if (window.screenX) { // Firefox and others
    browser.getWindowX = function() { return window.screenX; };
    browser.getWindowY = function() { return window.screenY; };
}

if (window.innerWidth) { // All browsers but IE
    browser.getViewportWidth = function() { return window.innerWidth; };
    browser.getViewportHeight = function() { return window.innerHeight; };
    browser.getHorizontalScroll = function() { return window.pageXOffset; };
    browser.getVerticalScroll = function() { return window.pageYOffset; };
}
else if (document.documentElement && document.documentElement.clientWidth) {
    // These functions are for IE 6 when there is a DOCTYPE
    browser.getViewportWidth =
        function() { return document.documentElement.clientWidth; };
    browser.getViewportHeight =
        function() { return document.documentElement.clientHeight; };
    browser.getHorizontalScroll =
        function() { return document.documentElement.scrollLeft; };
    browser.getVerticalScroll =
        function() { return document.documentElement.scrollTop; };
}
else if (document.body.clientWidth) {
    // for IE4, IE5, and IE6 without a DOCTYPE
    browser.getViewportWidth =
        function() { return document.body.clientWidth; };
    browser.getViewportHeight =
        function() { return document.body.clientHeight; };
    browser.getHorizontalScroll =
        function() { return document.body.scrollLeft; };
    browser.getVerticalScroll =
        function() { return document.body.scrollTop; };
}

// These functions return the size of the document. They are not window
// related, but they are useful to have here anyway.
if (document.documentElement && document.documentElement.scrollWidth) {
    browser.getDocumentWidth =
        function() { return document.documentElement.scrollWidth; };
    browser.getDocumentHeight =
        function() { return document.documentElement.scrollHeight; };
}
else if (document.body.scrollWidth) {
    browser.getDocumentWidth =
        function() { return document.body.scrollWidth; };
    browser.getDocumentHeight =
        function() { return document.body.scrollHeight; };
}


/* 用途：类似jquery的load方法
 * from(c)2006 Jesse Skinner/Dean Edwards/Matthias Miller/John Resig
 * To use: call addDOMLoadEvent one or more times with functions, ie:
 *
 *    function something() {
 *       // do something
 *    }
 *    addDOMLoadEvent(something);
 *
 *    addDOMLoadEvent(function() {
 *        // do other stuff
 *    });
 *
 */


var addDOMLoadEvent = (function(){
    // create event function stack
    var load_events = [],
        load_timer,
        script,
        done,
        exec,
        old_onload,
        init = function () {
            done = true;

            // kill the timer
            clearInterval(load_timer);

            // execute each function in the stack in the order they were added
            while (exec = load_events.shift())
                exec();

            if (script) script.onreadystatechange = '';
        };

    return function (func) {
        // if the init function was already ran, just run this function now and stop
        if (done) return func();

        if (!load_events[0]) {
            // for Mozilla/Opera9
            if (document.addEventListener)
                document.addEventListener("DOMContentLoaded", init, false);

            // for Internet Explorer
            /*@cc_on @*/
            /*@if (@_win32)
                document.write("<script id=__ie_onload defer src=//0><\/scr"+"ipt>");
                script = document.getElementById("__ie_onload");
                script.onreadystatechange = function() {
                    if (this.readyState == "complete")
                        init(); // call the onload handler
                };
            /*@end @*/

            // for Safari
            if (/WebKit/i.test(navigator.userAgent)) { // sniff
                load_timer = setInterval(function() {
                    if (/loaded|complete/.test(document.readyState))
                        init(); // call the onload handler
                }, 10);
            }

            // for other browsers set the window.onload, but also execute the old window.onload
            old_onload = window.onload;
            window.onload = function() {
                init();
                if (old_onload) old_onload();
            };
        }

        load_events.push(func);
    }
})();



function objectExtend(targetObject, sourceObject, extendProperties){ //类继承方法
	var p;
	for (p in sourceObject.prototype){ //拷贝方法和属性
		targetObject.prototype[p] = sourceObject.prototype[p];
	}
	for (p in extendProperties){ //扩展
		targetObject.prototype[p] = extendProperties[p];
	}
}

Function.prototype.bind = function(obj){
	var t = this;
	return function(){
		return t.apply(obj, arguments);
	}
};

//字符串->json
function parseJson(str){
	try{
		return eval("(" + str + ")");
	}catch(e){
		return str;
	}
}

if (!window.XMLHttpRequest)
var XMLHttpRequest = function(){
	return new ActiveXObject('Microsoft.XMLHTTP');
};

var ajax = { //ajax类
	get: function(url,callback,asynType){
		asynType = (false == asynType) ? false : true;
		(new request(url, callback, null, asynType)).doGet();
	},

	post: function(url, data, callback){
		(new request(url, callback, data, true)).doPost(); //没有写同步功能
	}
};

function request(url, callback, data, asynType){
	this.url = url;
	this.callback = callback;
	this.data = data;
	this.asynType = asynType;
	this.xmlRequest = new XMLHttpRequest();
}
request.prototype = {
	init:function(){
		if (this.asynType)	this.xmlRequest.onreadystatechange = this.checkStatus.bind(this); //异步
	},

	doGet:function(){
		this.init();
		this.url += (this.url.indexOf('?') > 0 ? '&' : '?') + 'r=' + Math.random();
		this.xmlRequest.open('GET', this.url, this.asynType);
		this.xmlRequest.send(null);

		if (false == this.asynType) { // 同步
			if (this.isSuccess()){
				return this.callback(this.xmlRequest.responseText);
			}
		}
	},

	doPost:function(){//执行post方法
		this.init();
		this.xmlRequest.open('POST', this.url, this.asynType);
		this.xmlRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
		this.xmlRequest.send(this.data);
	},

	checkStatus:function(){
		if(4 == this.xmlRequest.readyState){
			if(true == this.isSuccess())
				this.callback(this.xmlRequest.responseText);
			else
				debug('url:'+this.url+' data:'+this.data+' errorCode:'+this.xmlRequest.status+'msg:'+this.xmlRequest.responseText);
		}
	},

	isSuccess:function(){
		return this.xmlRequest.status < 300;
	}
};


function die(obj){
	for (p in obj)	obj[p] = null;
	obj = null;
}

function getPosition(){ //取得对象相对另一个对象的位置
	var domNode = arguments[0];
	var parentDiv = arguments[1] || document.body;
	var posTop = 0;
	var posLeft = 0;
	while (domNode != parentDiv){
		posTop += domNode.offsetTop;
		posLeft += domNode.offsetLeft;
		domNode = domNode.offsetParent;
	}
	return [posTop, posLeft];
}

var dom = {//dom节点操作静态类
	fix: {'class':'className','colspan':'colSpan','rowspan':'rowSpan'},
	newNode: function(){
		var tmpObj = document.createElement(arguments[0]);
		if (arguments[1]){
			var properties = arguments[1], tmpPro;
			for (pro in properties){
				tmpPro=this.fix[pro] || pro;
				tmpObj[tmpPro]=properties[pro];
			}
		}
		if (arguments[2])	arguments[2].appendChild(tmpObj);
		return tmpObj;
	},

	makeHtml: function(childs){ //批量生成DOM  childs的格式如['div' ,{'className':'test','id':'testDiv'}, 可选参数] 可选参数包括:dom, 'string' ,childs
		var childsLen = childs.length;
		var tmpNode = this.newNode(childs[0], childs[1]);
		var tmpChild;
		if (2 == childsLen)	return tmpNode; //如果没有可选参数,结束
		for (var i=2; i<childsLen; i++){
			tmpChild = childs[i];
			if (true == isArray(tmpChild))
				tmpNode.appendChild(this.makeHtml(tmpChild)); //如果是Array, 递归make
			else if ('string' == typeof(tmpChild) || 'number' == typeof(tmpChild))
				tmpNode.innerHTML += tmpChild; //如果是string或者number,直接加到innerHTML
			else{
				try{
					tmpNode.appendChild(tmpChild); //试试看是不是Dom
				}catch(e){

				}
			}
		}

		return tmpNode;
	},

	appendNodes: function(rootNode){
		for (var i = 1, l = arguments.length; i < l; i++){
			rootNode.appendChild(arguments[i]);
		}
	},

	removeEvent: function(rootNode){
		var nodes = rootNode.childNodes;
		for(var i=nodes.length-1; i>=0; i--){
			if (nodes[i].nodeType!=1)	continue;
			if (nodes[i].childNodes.length>0) //有子节点
				this.removeEvent(nodes[i]);
			else
				eve.stopAllObserve(nodes[i]); //删除绑定事件
		}
		eve.stopAllObserve(rootNode);
	},

	removeNodes: function(rootNode){
		this.removeEvent(rootNode); //首先判断子节点是否绑定有事件
		this.removeChilds(rootNode);
		rootNode = null;
		if (browser.msie)	CollectGarbage();
	},

	emptyNodes: function(rootNode) {
		this.removeEvent(rootNode);
		var nodes = rootNode.childNodes;
		for(var i = nodes.length-1; i >= 0; i--) {
			if (nodes[i].nodeType != 1)	continue;
			if (nodes[i].childNodes.length > 0)
				this.removeChilds(nodes[i]);
			else{
				try{
					rootNode.removeChild(nodes[i]);
					nodes[i] = null;
				}catch(e){}
			}
		}
		if (browser.msie)	CollectGarbage();
	},

	removeChilds: function(rootNode){ //删除节点
		var nodes = rootNode.childNodes;
		for(var i = nodes.length-1; i >= 0; i--){
			if (nodes[i].nodeType != 1)	continue;
			if (nodes[i].childNodes.length > 0)
				this.removeChilds(nodes[i]);
			else{
				try{
					rootNode.removeChild(nodes[i]);
					nodes[i] = null;
				}catch(e){}
			}
		}
		try{
			rootNode.parentNode.removeChild(rootNode);
		}catch(e){}
		rootNode = null;
	},

	getById: function(domId){
		return document.getElementById(domId);
	},

	getByName: function(rootNode, domName){
		return rootNode.getElementsByTagName(domName);
	},

	addClass: function(domNode,cssName){
		if (domNode.className.indexOf(cssName)>=0)	return;
		var s = ('' == domNode.className) ? '' : ' '; //如果已经有class了,要先空一格
		domNode.className += s + cssName;
	},

	removeClass: function(domNode, cssName){
		var t = domNode.className.indexOf(cssName);
		if (cssName == domNode.className)	return domNode.className = null;
		var s = '';
		if (-1 == t)	return;//没有这个class
		if (0 == t)
			s = cssName + ' ';//第一个class
		else
			s = ' ' + cssName; //不在第一个
		domNode.className = domNode.className.replace(s, '');
	},

	hideNode: function(domNode) {
		if (domNode) {
			domNode.style.visibility = "hidden";
		}
	},

	showNode: function(domNode) {
		if (domNode) {
			domNode.style.visibility = "";
		}
	}

};

var eve = {//事件静态类
	guid: 1, //给每个函数编号
	observe: function(domNode, eveType, handle, obj){
		//debug(domNode.nodeName+' '+domNode.className+' '+eveType + handle.toString()+'<br/><br/>');
		var fn = handle;
		if (!domNode.eve)	domNode.eve = {};
		if (!fn.eveGuid)	fn.eveGuid = this.guid++;
		handle = function(){
			return fn.apply(obj, arguments);
		}
		if (!domNode['eve'][eveType])	domNode['eve'][eveType] = {};
		domNode['eve'][eveType]['guid' + fn.eveGuid] = handle;
		if (browser.msie)
			domNode.attachEvent('on' + eveType, handle);
		else
			domNode.addEventListener(eveType, handle, false);
	},

	stopObserve: function(domNode, eveType, handle){//删除某一绑定事件
		var tmpHandle = [];
		var isHandle = true; //是否移除单个handle
		if (!handle){ //如果没有指定handle,则删除所有的eveType的事件
			for (h in domNode['eve'][eveType]){
				tmpHandle.push(domNode['eve'][eveType][h]);
			}
			isHandle = false;
		}else{
			tmpHandle.push(domNode['eve'][eveType]['guid' + handle.eveGuid]);
		}
		for (var i = tmpHandle.length-1; i>=0; i--){
			if (browser.msie)
				domNode.detachEvent("on" + eveType, tmpHandle[i]);
			else
				domNode.removeEventListener(eveType, tmpHandle[i], false);
		}
		if (true == isHandle)
			delete(domNode['eve'][eveType]['guid' + handle.eveGuid]);
		else
			delete(domNode['eve'][eveType]);
	},

	stopAllObserve: function(domNode){//删除一个dom节点绑定的所有事件
		if (!domNode.eve)	return;//没有绑定事件
		for (t in domNode['eve']){
			this.stopObserve(domNode, t);
		}
	}
};


function debug(str){//打印调试函数
	if (!!IS_DEBUG)
	dom.getById('debug').appendChild(dom.makeHtml(['div',{},str + '']));
}

function convertHTML(value) {
	if (!value) {
		return "";
	}
	return value.toString().split("<").join("&lt;").split(">").join("&gt;").split(" ").join("&nbsp;").split("&amp;").join("&").split("&lt;").join("<").split("&gt;").join(">");
}